package com.wiscamp.ninechapters.panels.application.services;

import com.wiscamp.ninechapters.panels.application.assemblers.DictionaryAssembler;
import com.wiscamp.ninechapters.panels.application.command.CreateDictionaryCommand;
import com.wiscamp.ninechapters.panels.application.command.UpdateDictionaryCommand;
import com.wiscamp.ninechapters.panels.application.vo.DictionaryVO;
import com.wiscamp.ninechapters.panels.domain.repositories.DictionaryRepository;
import com.wiscamp.ninechapters.panels.domain.services.DictionaryService;
import cube.ddd.application.BaseAppService;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.application.command.DisableCommand;
import cube.ddd.application.command.EnableCommand;
import cube.ddd.aspect.HandleServiceException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.AppServiceUtils;
import jakarta.validation.Valid;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class DictionaryAppService extends BaseAppService {

    private final DictionaryRepository dictionaryRepository;

    private final DictionaryService dictionaryService;

    public DictionaryAppService(DictionaryRepository dictionaryRepository, DictionaryService dictionaryService) {
        this.dictionaryRepository = dictionaryRepository;
        this.dictionaryService = dictionaryService;
    }

    @HandleServiceException
    public DictionaryVO getDictionary(long dictionaryId) {
        return AppServiceUtils.getById(dictionaryId, dictionaryService::getDictionary,
                DictionaryAssembler.Instance::toDictionaryVO);
    }

    @HandleServiceException
    public DictionaryVO getDictionaryByCode(long appId, String dictionaryCode) {
        return AppServiceUtils.getByIdAndText(appId, dictionaryCode, dictionaryRepository::getDictionaryByCode,
                DictionaryAssembler.Instance::toDictionaryVO);
    }

    @HandleServiceException
    public Collection<DictionaryVO> getDictionariesByName(long appId, String dictionaryName) {
        return AppServiceUtils.getListByIdAndText(appId, dictionaryName, dictionaryRepository::getDictionariesByName,
                DictionaryAssembler.Instance::toDictionaryVO);
    }

    @HandleServiceException
    public Collection<DictionaryVO> getDictionariesByGroup(long appId, String appGroup) {
        return AppServiceUtils.getListByIdAndText(appId, appGroup, dictionaryRepository::getDictionariesByGroup,
                DictionaryAssembler.Instance::toDictionaryVO);
    }

    @HandleServiceException
    public PagedObjects<DictionaryVO> getDictionariesByQuery(PagedQuery pagedQuery) {
        var pagedObjects = dictionaryRepository.getDictionariesByQuery(pagedQuery);
        return AppServiceUtils.convertPagedObjects(pagedObjects, DictionaryAssembler.Instance::toDictionaryVO);
    }

    @HandleServiceException
    public DictionaryVO createDictionary(@Valid CreateDictionaryCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), dictionaryService::createDictionary,
                DictionaryAssembler.Instance::toDictionaryVO, DictionaryAssembler.Instance::fromCreateCommand);
    }

    @HandleServiceException
    public DictionaryVO updateDictionary(@Valid UpdateDictionaryCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), dictionaryService::updateDictionary,
                DictionaryAssembler.Instance::toDictionaryVO, DictionaryAssembler.Instance::fromUpdateCommand);
    }

    @HandleServiceException
    public boolean deleteDictionary(@Valid DeleteCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), dictionaryService::deleteDictionary);
    }

    @HandleServiceException
    public boolean enableDictionary(@Valid EnableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.enable(command.getId(), command.getOperatorId(), dictionaryService::enableDictionary);
    }

    @HandleServiceException
    public boolean disableDictionary(@Valid DisableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.disable(command.getId(), command.getOperatorId(), dictionaryService::disableDictionary);
    }
}
